package org.txazo.blog.commons.scan;

import java.io.File;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.txazo.blog.util.ContextUtil;

/**
 * ActionUriScanner
 * 
 * @author Tu XiaoZhou
 * @since 2013-09-05
 * 
 */
public class ActionUriScanner implements UriScanner {

	/** Action基包 */
	private String baseActionPackage = "org.txazo.blog.web.action";
	/** 动态资源URI */
	private Set<String> uris = new HashSet<String>();
	/** Action类名 */
	private Set<String> classes = new HashSet<String>();

	@Override
	public Set<String> scan() {
		File parent = new File(ContextUtil.getWebClassPath());
		File[] childs = parent.listFiles();
		for (File child : childs) {
			String name = child.getName();
			if (child.isDirectory() && baseActionPackage.startsWith(name)) {
				scan(child, name);
			}
		}

		try {
			scanActionUri();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return uris;
	}

	private void scan(File directory, String packageName) {
		File[] childs = directory.listFiles();
		for (File child : childs) {
			String name = child.getName();
			if (child.isDirectory()
					&& (baseActionPackage.startsWith(packageName + "." + name) || baseActionPackage
							.equals(packageName))) {
				scan(child, packageName + "." + name);
			} else if (child.isFile() && name.endsWith(".class")) {
				classes.add(packageName + "."
						+ name.substring(0, name.indexOf(".")));
			}
		}
	}

	private void scanActionUri() throws ClassNotFoundException {
		for (String className : classes) {
			Class<?> proxyClass = ActionUriScanner.class.getClassLoader()
					.loadClass(className);
			if (className.contains("JsonAction")) {
				Method[] methods = proxyClass.getMethods();
				for (Method method : methods) {
					Action action = method.getAnnotation(Action.class);
					if (action != null) {
						uris.add("/json/" + action.value() + ".jsps");
					}
				}
			} else {
				Namespace nameSpace = proxyClass.getAnnotation(Namespace.class);
				if (nameSpace != null) {
					Method[] methods = proxyClass.getMethods();
					for (Method method : methods) {
						Action action = method.getAnnotation(Action.class);
						if (action != null) {
							if (nameSpace.value().equals("/")) {
								uris.add("/" + action.value() + ".jsps");
							} else {
								uris.add(nameSpace.value() + "/"
										+ action.value() + ".jsps");
							}
						}
					}
				}
			}
		}
	}

}
